package com.iengoo.spacewar;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import static com.iengoo.spacewar.Config.*;
import static com.iengoo.spacewar.Config.KEY_WORDS;
import static com.iengoo.spacewar.Config.START_TIME;
import static com.iengoo.spacewar.GameLevel.GAME_OVER;

/**
 * @author zpym
 * @CopyRight (C) http://www.iengoo.com
 * @brief 游戏关卡以及过程控制
 * @email 122162005@qq.com
 * @date 2018-12-26 22:55
 */
public class LevelManager {
    private volatile static LevelManager instance;
    private Craft craft;
    private static BufferedImage qrCode;
    private static BufferedImage logo;
    private static BufferedImage gameName;
    private static BufferedImage tips;
    private static BufferedImage startGame;
    private static BufferedImage[] startGameImages;
    private MineContainer mineList = MineContainer.getInstance();
    private int adTextIndex = 1;
    private String adText = "这是一个相对比较公平的行业; 不用拼爹,不是富二代,不用喝酒应酬,不用各种人脉关系; 只要你愿意努力,热爱,付出一定的时间,再加上不算太笨的大脑,我们一起一定可以改变你的未来！";


    public static LevelManager getLevelManager(Craft craft) {
        if (instance == null) {
            synchronized (LevelManager.class) {
                // 请注意为什么要放到if中去创建对象，而不是直接创建
                // instance = new LevelManager(craft);
                if (instance == null) {
                    instance = new LevelManager(craft);
                }
            }
        }

        return instance;
    }

    private LevelManager(Craft craft) {
        this.craft = craft;
        init();
    }

    private void init() {
        try {
            qrCode = ImageIO.read(getClass().getResource("resources/qr_code.png"));
            logo = ImageIO.read(getClass().getResource("resources/logo_white_font.png"));
//            gameName = ImageIO.read(getClass().getResource("resources/game_name_white.png"));
            gameName = ImageIO.read(getClass().getResource("resources/game_name.png"));
            tips = ImageIO.read(getClass().getResource("resources/tips.png"));
            startGameImages = new BufferedImage[] {
                    ImageIO.read(getClass().getResource("resources/start_game.png")),
                    ImageIO.read(getClass().getResource("resources/start_game_orange.png"))
            };
            startGame = startGameImages[0];
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setStartGame2Orange(JPanel mainPanel) {
        if (!startGame.equals(startGameImages[1])) {
            startGame = startGameImages[1];
            // 改变panel中鼠标样式
            mainPanel.setCursor(new Cursor(Cursor.HAND_CURSOR));
        }
    }

    public void setStartGame2White(JPanel mainPanel) {
        if (!startGame.equals(startGameImages[0])) {
            startGame = startGameImages[0];
            // 改变panel中鼠标样式
            mainPanel.setCursor(Cursor.getDefaultCursor());
        }
    }
    /**
     * 游戏开始运行
     * @param g
     */
    public void runGame(Graphics g) {
        try {
            if (CURRENT_GAME_LEVEL == GameLevel.ad) {
                ad(g);
            } else if (CURRENT_GAME_LEVEL == GameLevel.LEVEL_01) {
                level01(g);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 游戏初始化时控制方法
     */
    public void ad(Graphics g) throws IOException {
        g.setColor(Color.WHITE);

        if (adTextIndex < adText.length() * 10) {
            if (adTextIndex < 300) {
                g.drawString(adText.substring(0, adTextIndex++ / 10), 30, 15);
            } else if (adTextIndex < 620) {
                g.drawString(adText.substring(0, 30), 30, 15);
                g.drawString(adText.substring(30, adTextIndex++ / 10), 10, 30);
            } else if (adTextIndex < adText.length() * 10) {
                g.drawString(adText.substring(0, 30), 30, 15);
                g.drawString(adText.substring(30, 62), 10, 30);
                g.drawString(adText.substring(62, adTextIndex++ / 10), 10, 45);
            }
        } else {
            g.drawString(adText.substring(0, 30), 30, 15);
            g.drawString(adText.substring(30, 62), 10, 30);
            g.drawString(adText.substring(62, adText.length()), 10, 45);
        }


        g.drawImage(logo, (PANEL_WIDTH - logo.getWidth()) / 2, 100, logo.getWidth(), logo.getHeight(), null);
        g.drawImage(gameName, (PANEL_WIDTH - gameName.getWidth()) / 2, 200, gameName.getWidth(), gameName.getHeight(), null);
        g.drawImage(tips, (PANEL_WIDTH - tips.getWidth()) / 2, 260, tips.getWidth(), tips.getHeight(), null);
        g.drawImage(startGame, (PANEL_WIDTH - startGame.getWidth()) / 2, 320, startGame.getWidth(), startGame.getHeight(), null);
        g.drawImage(qrCode, (PANEL_WIDTH - qrCode.getWidth()) / 2, 400, qrCode.getWidth(), qrCode.getHeight(), null);
        g.drawString("本游戏由博优教育出品", 240, PANEL_HEIGHT - 50);
    }


    public void level01(Graphics g) {
        for (int i = 0; i < mineList.size(); i++) {
            mineList.get(i).paint(g);
        }

        if (craft != null) {
            for (Plasma p : craft.getPlasmaList()) {
                p.paint(g);
            }
        }


        // 绘制爆炸效果
        BombContainer bc = BombContainer.getInstance();
        for (int i = 0; i < bc.size(); i++) {
            bc.get(i).paint(g);
        }

        if (craft != null) {
            craft.paint(g);
        }

    }

    /**
     * 生成地雷
     */
    public void generateMine() {
        MineContainer mineList = MineContainer.getInstance();
        if (STATUS == GameStatus.START) {  // 如果游戏处于开始状态且处于第一关，生成3个单词
            if (CURRENT_GAME_LEVEL == GameLevel.LEVEL_01) {
                /* 初始化生成地雷 start */
                // 1秒钟生成一个地雷
                if (System.currentTimeMillis() - START_TIME > 104000) {
                    return;
                } else if (mineList.size() == 2 && System.currentTimeMillis() - START_TIME > 3000) {
                    try {
                        mineList.add(new Mine(KEY_WORDS.get((int) (Math.random() * KEY_WORDS.size())), craft));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else if (mineList.size() == 1 && System.currentTimeMillis() - START_TIME > 2000) {
                    try {
                        mineList.add(new Mine(KEY_WORDS.get((int) (Math.random() * KEY_WORDS.size())), craft));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else if (mineList.size() == 0 && System.currentTimeMillis() - START_TIME > 1000) {
                    try {
                        mineList.add(new Mine(KEY_WORDS.get((int) (Math.random() * KEY_WORDS.size())), craft));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 地雷遇到飞船便，删除地雷
     */
    public void mineHitCraft() {
        MineContainer mineList = MineContainer.getInstance();
        if (craft == null) {
            return;
        }

        for (int i = 0; i < mineList.size(); i++) {
            Mine mine = mineList.get(i);
            if (mine.getY()
                    > craft.getY()) {
                MineContainer.getInstance().remove(mine);
                try {
                    BombContainer.getInstance().add(new Bomb(craft.getX(), craft.getY()));
                    BombContainer.getInstance().add(new Bomb(craft.getX(), craft.getY()));
                    BombContainer.getInstance().add(new Bomb(craft.getX(), craft.getY()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                craft = null;
//                Config.CURRENT_GAME_LEVEL = GAME_OVER;
                break;
            }
        }
    }

    /**
     * 离子炮超出游戏界面，便删除
     */
    public void plasmaOutOfBound() {
        if (craft == null) {
            return;
        }
        List<Plasma> plasmaList = craft.getPlasmaList();

        for (int i = 0; i < plasmaList.size(); i++) {
            Plasma plasma = plasmaList.get(i);
            if (plasma.getY() < -Plasma.SIZE + 50) {
                plasmaList.remove(plasma);
            }
        }
    }

    /**
     * 粒子炮是否创建地雷
     *
     * @param p
     * @param m
     */
    public boolean plasmaHitMine(Plasma p, Mine m) {
        boolean wasHit = false;

        if (p.getY() + Plasma.SIZE / 2 < m.getY()) {
            wasHit = true;
        }

        return wasHit;
    }

    public void recoveryAll() {
        BombContainer instance = BombContainer.getInstance();
        for (int i = 0; i < instance.size(); i++) {
            Bomb bomb = instance.get(i);
            Iterator<Bomb.BlastCoordinate> iterator = bomb.getCurrentBCs().iterator();
            while (iterator.hasNext()) {
                Bomb.BlastCoordinate bc = iterator.next();
                if (System.currentTimeMillis() - instance.get(i).getCreateTime() > (long) (bc.getLiveTime() * 1000)) {
                    iterator.remove();
                }

            }

            /**
             * 增强for循环本质只是编译前语法（或者说概念），不清楚的小伙伴可以参考这篇博客
             * https://xiangshouxiyang.iteye.com/blog/2369083,
             * 编译时编译器会对代码进行优化，导致字节码中本质是迭代器，
             * 也就是说，下面增强for循环代码本质应该是这个样子的
             *
             * Iterator iterator = bomb.getCurrentBCs().iterator();
             *
             * while(iterator.hasNext()) {
             *     BlastCoordinate bc = (BlastCoordinate)iterator.next();   // -->迭代器的next
             *     if (System.currentTimeMillis() - instance.get(i).getCreateTime() > (long)(bc.getLiveTime() * 1000)) {
             *         instance.get(i).getCurrentBCs().remove(bc);  // list自己的remove 方法
             *     }
             *  }
             *
             * 上面代码中remove方法是List 自己的而不是 iterator对象的方法，会导致
             * iterator 对象在调用next()方法时 modCount != expectedModCount
             * 因此下面代码在运行时会抛出
             * java.util.ConcurrentModificationException 异常
             * 如果小伙伴们不明白的话，请参考博客：
             * https://www.cnblogs.com/snowater/p/8024776.html
             */
            /*for (Bomb.BlastCoordinate bc : bomb.getCurrentBCs()) {
                if (System.currentTimeMillis() - instance.get(i).getCreateTime() > bc.getLiveTime() * 1000) {
                    instance.get(i).getCurrentBCs().remove(bc);
                }
            }*/
        }
    }
}
